// **************************************************************
// COPYRIGHT(c)2020, Xidian University
// All rights reserved.
//
// IP LIB INDEX : 
// IP Name      : 
//                
// File name    :
// Module name  :   0868122122222222222222`                                                                            ```````````````````````````````````````````````
// Full name    :
//
// Author       :  Hbing 
// Email        :  2629029232@qq.com
// Data         :  2020/8/24
// Version      :  V 1.0 
// 
//Abstract      :
// Called by    :  Father Module
// 
// Modification history
// ------------------------------------------------------------------------------------------------------
// 
//  
// *********************************************************************
// `include "top_define.v"
// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// DESCRIPTION
// *******************
// 根据物理队长信息以及crossbar交叉节点准备接收信息产生发送信息FIFO(tx_fifo--队列号)
// 
// 
//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
module tx_request_gen(
	//sysrem input/output
	input  wire 		clk  ,
	input  wire 		rst_n,
	//CPU配置DWRR使能
	input  wire         DWRR_en,
	//with port_state_bit_mux
	// input  wire [ 4:0]  port_state_bit      ,
	// output wire [ 2:0]  port_state_bit_clear,

	(*mark_debug = "true"*) input  wire [ 2:0] 	port_state_bit_set,
	(*mark_debug = "true"*) input  wire  	   	port_state_bit_val,
	//with queue_infor_management
    // output reg          dequeue_indicate_length_wr_en  ,
    // output reg  [ 2:0]  dequeue_indicate_length_wr_addr,
    // output reg  [63:0]  dequeue_indicate_length_wr_data,
    // input  wire [63:0]  dequeue_indicate_length_rd_data,
    // input  wire         indicate_length_wren_a,
    // input  wire [ 2:0]  indicate_length_addr_a,
    // input  wire [63:0]  indicate_length_din_a ,
    (*mark_debug = "true"*) output reg [63:0] 	dequeue_indicate_length_wr_data,
	(*mark_debug = "true"*) output reg [ 2:0] 	dequeue_indicate_length_wr_addr,
	(*mark_debug = "true"*) output reg  	  	dequeue_indicate_length_wr_en  ,

    (*mark_debug = "true"*) input  wire 		enqueue_indicate_length_wr_en,   
	(*mark_debug = "true"*) input  wire [ 2:0] 	enqueue_indicate_length_wr_addr, 
	(*mark_debug = "true"*) input  wire [63:0]  enqueue_indicate_length_wr_data, 
	(*mark_debug = "true"*) output reg  [63:0]  enqueue_indicate_length_rd_data,        
    //with schedule_dequeue
    /*(*mark_debug = "true"*)*/ input  wire 		tx_fifo_full_mul ,
    /*(*mark_debug = "true"*)*/ output reg  		tx_fifo_wren_mul ,
    /*(*mark_debug = "true"*)*/ output reg  [ 9:0]  tx_fifo_wdata_mul,  //4bit端口列表独热码+6bit队列号

    /*(*mark_debug = "true"*)*/ input  wire 		tx_fifo_full_7 ,
    /*(*mark_debug = "true"*)*/ output reg  		tx_fifo_wren_7 ,
    /*(*mark_debug = "true"*)*/ output reg  [ 5:0]  tx_fifo_wdata_7,  //队列号
    input  wire 		tx_fifo_full_6 ,
    output reg  		tx_fifo_wren_6 ,
    output reg  [ 5:0]  tx_fifo_wdata_6,  //队列号
    input  wire 		tx_fifo_full_5 ,
    output reg  		tx_fifo_wren_5 ,
    output reg  [ 5:0]  tx_fifo_wdata_5,  //队列号
    input  wire 		tx_fifo_full_4 ,
    output reg  		tx_fifo_wren_4 ,
    output reg  [ 5:0]  tx_fifo_wdata_4,  //队列号
    input  wire 		tx_fifo_full_3 ,
    output reg  		tx_fifo_wren_3 ,
    output reg  [ 5:0]  tx_fifo_wdata_3,  //队列号
    input  wire 		tx_fifo_full_2 ,
    output reg  		tx_fifo_wren_2 ,
    output reg  [ 5:0]  tx_fifo_wdata_2,  //队列号
    input  wire 		tx_fifo_full_1 ,
    output reg  		tx_fifo_wren_1 ,
    output reg  [ 5:0]  tx_fifo_wdata_1,  //队列号
    input  wire 		tx_fifo_full_0 ,
    output reg  		tx_fifo_wren_0 ,
    output reg  [ 5:0]  tx_fifo_wdata_0,  //队列号
    //with crossbar_ctrl_top
    /*(*mark_debug = "true"*)*/ input  wire 		uni_tx_rdy0,
    /*(*mark_debug = "true"*)*/ input  wire 		uni_tx_rdy1,
    /*(*mark_debug = "true"*)*/ input  wire 		uni_tx_rdy2,
    /*(*mark_debug = "true"*)*/ input  wire 		uni_tx_rdy3,
    /*(*mark_debug = "true"*)*/ input  wire 		mul_tx_rdy0,
    /*(*mark_debug = "true"*)*/ input  wire 		mul_tx_rdy1,
    /*(*mark_debug = "true"*)*/ input  wire 		mul_tx_rdy2,
    /*(*mark_debug = "true"*)*/ input  wire 		mul_tx_rdy3,
    //with schedule_enqueue
    /*(*mark_debug = "true"*)*/ input  wire 		sr_rx_mul_fifo_empty,
    /*(*mark_debug = "true"*)*/ output reg  		sr_rx_mul_fifo_rden ,
    /*(*mark_debug = "true"*)*/ input  wire [ 3:0]  sr_rx_mul_fifo_rdata
	);

//*******************
//DEFINE PARAMETER
//*******************
//Parameter(s) 
localparam IDLE           = 6'b00_0000;
localparam PORT_POLLING   = 6'b00_0001;
localparam READ_INFO      = 6'b00_0010;
localparam WR_MUL_TXFIFO  = 6'b00_0100;
localparam WR_UNI_TXFIFO  = 6'b00_1000;
localparam UPDATE         = 6'b01_0000;
localparam FINISH         = 6'b10_0000;
//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
//状态机
(*mark_debug = "true"*) reg [5:0] c_state,n_state;
//端口列表
(*mark_debug = "true"*) reg [4:0] port_state_bit;
//用于指示bit掩码表中1的位置，轮询单播目的端口号
(*mark_debug = "true"*) reg [2:0] dequeue_NodeID_uni;
//出队数据帧端口号--组合逻辑,当前拍，为了给出物理队长读地址
(*mark_debug = "true"*) reg [2:0] dequeue_NodeID_c;
//寄存dequeu_NodeID_c
(*mark_debug = "true"*) reg [2:0] dequeue_NodeID;
//出队数据帧优先级
(*mark_debug = "true"*) reg [2:0] dequeue_pri;
//多播出队优先级
reg [2:0] dequeue_mul_pri;
//寄存多播转发列表
reg [3:0] mul_ouport_list;
//物理队列信息存储
reg [63:0] indicate_length_data_node0  ;
reg [63:0] indicate_length_data_node1  ;
reg [63:0] indicate_length_data_node2  ;
reg [63:0] indicate_length_data_node3  ;
reg [63:0] indicate_length_data_mul    ;
// 多播fifo寄存
reg [ 3:0]  sr_rx_mul_fifo_rdata_reg   ;
//入队物理队长寄存
/*(*mark_debug = "true"*)*/ reg [63:0] dequeue_indicate_length_rd_data_c;
/*(*mark_debug = "true"*)*/ reg [63:0] dequeue_indicate_length_rd_data;
/*(*mark_debug = "true"*)*/ reg [63:0] enqueue_indicate_length_rd_data_tmp;
/*(*mark_debug = "true"*)*/ reg [63:0] enqueue_indicate_length_rd_data_reg;
//物理队列长度统计
reg [10:0] indicate_length_sum0;
reg [10:0] indicate_length_sum1;
reg [10:0] indicate_length_sum2;
reg [10:0] indicate_length_sum3;
reg [10:0] indicate_length_sum4;
//WIRES
//判断物理队长哪个个优先级有数据
wire is_pri_7,is_pri_6,is_pri_5,is_pri_4,is_pri_3,is_pri_2,is_pri_1,is_pri_0;
//组合7个判断结果
(*mark_debug = "true"*) wire [7:0] dequeue_pri_c;
//组合7个优先级满标志
(*mark_debug = "true"*) wire [7:0] tx_fifo_full_uni;
//多播对应转发端口号全部准备好
wire mul_match_en;
//单播转发端口号准备好
wire uni_match_en;	

//*********************
//INSTANTCE MODULE
//*********************
//多播fifo寄存
always @(posedge clk or negedge rst_n) begin
	if(~rst_n) begin
		sr_rx_mul_fifo_rdata_reg <= 4'b0;
	end
	else begin
		sr_rx_mul_fifo_rdata_reg <= sr_rx_mul_fifo_rdata;		
	end
end
//*********************
//MAIN CORE
//*********************
assign tx_fifo_full_uni = {tx_fifo_full_7,tx_fifo_full_6,tx_fifo_full_5,tx_fifo_full_4,tx_fifo_full_3,tx_fifo_full_2,tx_fifo_full_1,tx_fifo_full_0};

//物理队长输出--与bus_rx交互
always @(*) begin
	if (!enqueue_indicate_length_wr_en) begin
		case (enqueue_indicate_length_wr_addr)
			3'd0: begin
				enqueue_indicate_length_rd_data_tmp = indicate_length_data_node0;
			end
			3'd1: begin
				enqueue_indicate_length_rd_data_tmp = indicate_length_data_node1;
			end
			3'd2: begin
				enqueue_indicate_length_rd_data_tmp = indicate_length_data_node2;
			end
			3'd3: begin
				enqueue_indicate_length_rd_data_tmp = indicate_length_data_node3;
			end
			3'd4: begin
				enqueue_indicate_length_rd_data_tmp = indicate_length_data_mul;
			end
			default: begin
				enqueue_indicate_length_rd_data_tmp = 64'b0;
			end
		endcase
	end
	else begin
		enqueue_indicate_length_rd_data_tmp = enqueue_indicate_length_rd_data_reg;
	end
end

always @(*) begin
	if((c_state == UPDATE) && (dequeue_NodeID == enqueue_indicate_length_wr_addr)) begin
		 // case(dequeue_pri)
		 //    3'b000: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63: 8],enqueue_indicate_length_rd_data_tmp[ 7: 0]-8'd1};
   //          3'b001: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:16],enqueue_indicate_length_rd_data_tmp[15: 8]-8'd1,enqueue_indicate_length_rd_data_tmp[7:0]};
   //          3'b010: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:24],enqueue_indicate_length_rd_data_tmp[23:16]-8'd1,enqueue_indicate_length_rd_data_tmp[15:0]};
   //          3'b011: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:32],enqueue_indicate_length_rd_data_tmp[31:24]-8'd1,enqueue_indicate_length_rd_data_tmp[23:0]};
   //          3'b100: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:40],enqueue_indicate_length_rd_data_tmp[39:32]-8'd1,enqueue_indicate_length_rd_data_tmp[31:0]};
   //          3'b101: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:48],enqueue_indicate_length_rd_data_tmp[47:40]-8'd1,enqueue_indicate_length_rd_data_tmp[39:0]};
   //          3'b110: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:56],enqueue_indicate_length_rd_data_tmp[55:48]-8'd1,enqueue_indicate_length_rd_data_tmp[47:0]};
   //          3'b111: enqueue_indicate_length_rd_data = {enqueue_indicate_length_rd_data_tmp[63:56]-8'd1,enqueue_indicate_length_rd_data_tmp[55:0]};
   //          default:enqueue_indicate_length_rd_data = enqueue_indicate_length_rd_data_tmp;
   //      endcase
   		enqueue_indicate_length_rd_data = dequeue_indicate_length_wr_data;
	end
	else begin
		enqueue_indicate_length_rd_data = enqueue_indicate_length_rd_data_tmp;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		enqueue_indicate_length_rd_data_reg <= 64'b0;
	end
	else begin
		enqueue_indicate_length_rd_data_reg <= enqueue_indicate_length_rd_data;
	end
end

//三段式状态机
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		c_state <= IDLE;
	end
	else begin
		c_state <= n_state;
	end
end

always @(*) begin
	case(c_state)
		IDLE:
		begin
			if (port_state_bit != 5'd0) begin  //bit掩码表不全为0，代表有入队数据
				n_state = PORT_POLLING;
			end
			else begin
				n_state = IDLE;
			end
		end
		PORT_POLLING:
		begin
			begin
			if ((dequeue_NodeID_c == 3'd4) && (sr_rx_mul_fifo_empty == 1'b0)) begin
				n_state = WR_MUL_TXFIFO;
			end
			else if ((dequeue_NodeID_c <= 3'd3) && (dequeue_NodeID_c >= 3'd0)) begin
				n_state = WR_UNI_TXFIFO;
			end
			else begin  //此情况应该不存在
				n_state = PORT_POLLING;
			end
		end
		end
		// READ_UNI_INFO:
		// begin
		// 	n_state = WR_UNI_TXFIFO;
		// end
		// READ_MUL_INFO:
		// begin
		// 	n_state = WR_MUL_TXFIFO;
		// end
		WR_MUL_TXFIFO:
		begin
			if ((mul_match_en == 1'b1) && (tx_fifo_full_mul == 1'b0)) begin  //多播等待转发端口转发好一起转发
				n_state = UPDATE;
			end
			else begin
				// n_state = WR_MUL_TXFIFO;
				n_state = IDLE;
			end
		end
		WR_UNI_TXFIFO:
		begin
			if ((uni_match_en == 1'b1) && (tx_fifo_full_uni[dequeue_pri] == 1'b0)) begin
				n_state = UPDATE;
			end
			// else if (uni_match_en == 1'b1) begin  //端口准备好，但是对应tx_fifo已满，应该不会出现--现在可能会出现
			// 	n_state = WR_UNI_TXFIFO;
			// end
			else begin  //轮询下一端口
				n_state = IDLE;
			end
		end
		UPDATE:
		begin
			n_state = IDLE;
		end
		default:
		begin
			n_state = IDLE;
		end
	endcase
end

//用于指示bit掩码表中1的位置，轮询单播目的端口号
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_NodeID_uni <= 3'd3;  //从0号端口开始递增轮询
	end
	else if ((c_state == IDLE) && (port_state_bit[3:0] != 4'd0)) begin
		if (port_state_bit[(dequeue_NodeID_uni > 3'd2) ? (dequeue_NodeID_uni - 3'd3):(dequeue_NodeID_uni + 3'd1)] == 1'b1) begin
			dequeue_NodeID_uni <= (dequeue_NodeID_uni > 3'd2) ? (dequeue_NodeID_uni - 3'd3):(dequeue_NodeID_uni + 3'd1);
		end
		else if (port_state_bit[(dequeue_NodeID_uni > 3'd1) ? (dequeue_NodeID_uni - 3'd2):(dequeue_NodeID_uni + 3'd2)] == 1'b1) begin
			dequeue_NodeID_uni <= (dequeue_NodeID_uni > 3'd1) ? (dequeue_NodeID_uni - 3'd2):(dequeue_NodeID_uni + 3'd2);
		end
		else if (port_state_bit[(dequeue_NodeID_uni > 3'd0) ? (dequeue_NodeID_uni - 3'd1):(dequeue_NodeID_uni + 3'd3)] == 1'b1) begin
			dequeue_NodeID_uni <= (dequeue_NodeID_uni > 3'd0) ? (dequeue_NodeID_uni - 3'd1):(dequeue_NodeID_uni + 3'd3);
		end
		else begin
			dequeue_NodeID_uni <= dequeue_NodeID_uni;
		end
	end
	else begin
		dequeue_NodeID_uni <= dequeue_NodeID_uni;
	end
end

//查询bit掩码表得知出队的端口号
always @(*) begin
	if (port_state_bit != 5'd0) begin
		if (port_state_bit[4] == 1'b1) begin
			dequeue_NodeID_c = 3'd4;
		end
		else begin  //单播需要轮询端口
			dequeue_NodeID_c = dequeue_NodeID_uni;
		end
	end
	else begin
		dequeue_NodeID_c = 3'd0;
	end
end

//在IDLE到下一个状态寄存出队帧目的端口号
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_NodeID <= 3'd0;
	end
	else if (c_state == PORT_POLLING) begin
		dequeue_NodeID <= dequeue_NodeID_c;
	end
	else begin
		dequeue_NodeID <= dequeue_NodeID;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_indicate_length_rd_data <= 64'd0;
	end
	else if (c_state == PORT_POLLING) begin
		dequeue_indicate_length_rd_data <= dequeue_indicate_length_rd_data_c;
	end
	else begin
		dequeue_indicate_length_rd_data <= dequeue_indicate_length_rd_data;
	end
end

always @(*) begin
	case(dequeue_NodeID_c)
	3'd0: dequeue_indicate_length_rd_data_c = indicate_length_data_node0;
	3'd1: dequeue_indicate_length_rd_data_c = indicate_length_data_node1;
	3'd2: dequeue_indicate_length_rd_data_c = indicate_length_data_node2;
	3'd3: dequeue_indicate_length_rd_data_c = indicate_length_data_node3;
	3'd4: dequeue_indicate_length_rd_data_c = indicate_length_data_mul;
	default: dequeue_indicate_length_rd_data_c = 64'b0;
	endcase
end

//出队数据帧优先级
assign is_pri_0 = (dequeue_indicate_length_rd_data_c[ 7: 0] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_1 = (dequeue_indicate_length_rd_data_c[15: 8] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_2 = (dequeue_indicate_length_rd_data_c[23:16] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_3 = (dequeue_indicate_length_rd_data_c[31:24] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_4 = (dequeue_indicate_length_rd_data_c[39:32] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_5 = (dequeue_indicate_length_rd_data_c[47:40] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_6 = (dequeue_indicate_length_rd_data_c[55:48] != 8'd0) ? 1'b1: 1'b0;
assign is_pri_7 = (dequeue_indicate_length_rd_data_c[63:56] != 8'd0) ? 1'b1: 1'b0;

assign dequeue_pri_c = {is_pri_7,is_pri_6,is_pri_5,is_pri_4,is_pri_3,is_pri_2,is_pri_1,is_pri_0};


//公平轮询？？
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_pri <= 3'd0;
	end
	else if ((DWRR_en == 1'b1) && (c_state == PORT_POLLING)) begin  //开启DWRR调度,端口内部发送调度轮询优先级写入,由总线执行调度进行反压
		if (dequeue_pri_c[(dequeue_pri > 3'd0) ? (dequeue_pri-3'd1):(dequeue_pri+3'd7)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd0) ? (dequeue_pri-3'd1):(dequeue_pri+3'd7);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd1) ? (dequeue_pri - 3'd2):(dequeue_pri + 3'd6)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd1) ? (dequeue_pri - 3'd2):(dequeue_pri + 3'd6);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd2) ? (dequeue_pri - 3'd3):(dequeue_pri + 3'd5)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd2) ? (dequeue_pri - 3'd3):(dequeue_pri + 3'd5);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd3) ? (dequeue_pri - 3'd4):(dequeue_pri + 3'd4)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd3) ? (dequeue_pri - 3'd4):(dequeue_pri + 3'd4);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd4) ? (dequeue_pri - 3'd5):(dequeue_pri + 3'd3)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd4) ? (dequeue_pri - 3'd5):(dequeue_pri + 3'd3);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd5) ? (dequeue_pri - 3'd6):(dequeue_pri + 3'd2)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd5) ? (dequeue_pri - 3'd6):(dequeue_pri + 3'd2);
		end
		else if (dequeue_pri_c[(dequeue_pri > 3'd6) ? (dequeue_pri - 3'd7):(dequeue_pri + 3'd1)] == 1'b1) begin
			dequeue_pri <= (dequeue_pri > 3'd6) ? (dequeue_pri - 3'd7):(dequeue_pri + 3'd1);
		end
		else begin
			dequeue_pri <= dequeue_pri;
		end
	end
	else if ((DWRR_en == 1'b0) && (c_state == PORT_POLLING)) begin  //不开启DWRR调度,端口内部严格优先级写入,总线执行严格优先级调度
		casex(dequeue_pri_c)
			8'b1xxx_xxxx: dequeue_pri <= 3'd7;
			8'b01xx_xxxx: dequeue_pri <= 3'd6;
			8'b001x_xxxx: dequeue_pri <= 3'd5;
			8'b0001_xxxx: dequeue_pri <= 3'd4;
			8'b0000_1xxx: dequeue_pri <= 3'd3;
			8'b0000_01xx: dequeue_pri <= 3'd2;
			8'b0000_001x: dequeue_pri <= 3'd1;
			default     : dequeue_pri <= 3'd0;
		endcase
	end
	else begin
		dequeue_pri <= dequeue_pri;
	end
end
//assign dequeue_pri = dequeue_mul_pri;

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_mul_pri <= 3'b0;
	end
	else if ((c_state == PORT_POLLING) /*&& (n_state == WR_MUL_TXFIFO)*/) begin  //多播无优先级，都为0
		casex(dequeue_pri_c)
			8'b1xxx_xxxx: dequeue_mul_pri <= 3'd7;
			8'b01xx_xxxx: dequeue_mul_pri <= 3'd6;
			8'b001x_xxxx: dequeue_mul_pri <= 3'd5;
			8'b0001_xxxx: dequeue_mul_pri <= 3'd4;
			8'b0000_1xxx: dequeue_mul_pri <= 3'd3;
			8'b0000_01xx: dequeue_mul_pri <= 3'd2;
			8'b0000_001x: dequeue_mul_pri <= 3'd1;
			default     : dequeue_mul_pri <= 3'd0;
		endcase
	end
	else begin
		dequeue_mul_pri <= dequeue_mul_pri;
	end
end

//多播队列非空，拉高多播端口列表FIFO(sr_rx_mul_fifo)读使能--首字置出
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		sr_rx_mul_fifo_rden <= 1'b0;
	end
	//else if ((c_state == PORT_POLLING) && ((dequeue_NodeID_c == 3'd4) && (sr_rx_mul_fifo_empty == 1'b0))) begin
	else if ((c_state == WR_MUL_TXFIFO) && (mul_match_en == 1'b1) && (tx_fifo_full_mul == 1'b0)) begin
		sr_rx_mul_fifo_rden <= 1'b1;
	end
	else begin
		sr_rx_mul_fifo_rden <= 1'b0;
	end
end

//寄存读数据--首字置出FIFO，先用数据
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		mul_ouport_list <= 4'd0;
	end
	else if (c_state == PORT_POLLING) begin
		mul_ouport_list <= sr_rx_mul_fifo_rdata_reg;
	end
	// else if (c_state == IDLE) begin
	// 	mul_ouport_list <= 4'd0;
	// end
	else begin
		mul_ouport_list <= mul_ouport_list;
	end
end

//多播对应转发端口号全部准备好 -- 目的端口有但是端口未准备好，不能match
assign mul_match_en = ~((mul_ouport_list[0] && !mul_tx_rdy0) || (mul_ouport_list[1] && !mul_tx_rdy1) ||
						(mul_ouport_list[2] && !mul_tx_rdy2) || (mul_ouport_list[0] && !mul_tx_rdy3));

//单播转发端口号准备好
assign uni_match_en = ((dequeue_NodeID == 3'd0) && uni_tx_rdy0) || ((dequeue_NodeID == 3'd1) && uni_tx_rdy1) ||
					  ((dequeue_NodeID == 3'd2) && uni_tx_rdy2) || ((dequeue_NodeID == 3'd3) && uni_tx_rdy3);

//写发送调度tx_fifo
	//多播
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		tx_fifo_wdata_mul <= 10'b0;
		tx_fifo_wren_mul  <= 1'b0;
	end
	else if ((c_state == WR_MUL_TXFIFO) && (mul_match_en) && (~tx_fifo_full_mul)) begin
		tx_fifo_wdata_mul <= {mul_ouport_list,dequeue_NodeID,dequeue_mul_pri};
		tx_fifo_wren_mul  <= 1'b1;
	end
	else begin
		tx_fifo_wdata_mul <= 10'b0;
		tx_fifo_wren_mul  <= 1'b0;
	end
end
	//单播
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		tx_fifo_wdata_7 <= 6'd0;
		tx_fifo_wren_7  <= 1'b0;
		tx_fifo_wdata_6 <= 6'd0;
		tx_fifo_wren_6  <= 1'b0;
		tx_fifo_wdata_5 <= 6'd0;
		tx_fifo_wren_5  <= 1'b0;
		tx_fifo_wdata_4 <= 6'd0;
		tx_fifo_wren_4  <= 1'b0;
		tx_fifo_wdata_3 <= 6'd0;
		tx_fifo_wren_3  <= 1'b0;
		tx_fifo_wdata_2 <= 6'd0;
		tx_fifo_wren_2  <= 1'b0;
		tx_fifo_wdata_1 <= 6'd0;
		tx_fifo_wren_1  <= 1'b0;
		tx_fifo_wdata_0 <= 6'd0;
		tx_fifo_wren_0  <= 1'b0;
	end
	else if ((c_state == WR_UNI_TXFIFO) && (uni_match_en == 1'b1) && (tx_fifo_full_uni[dequeue_pri] == 1'b0)) begin
	case(dequeue_pri)
		3'b111:
		begin
			tx_fifo_wdata_7 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_7  <= 1'b1;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b110:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_6  <= 1'b1;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b101:
		begin
			tx_fifo_wdata_7 <= 1'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_5  <= 1'b1;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b100:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_4  <= 1'b1;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b011:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_3  <= 1'b1;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b010:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_2  <= 1'b1;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b001:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_1  <= 1'b1;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
		3'b000:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= {dequeue_NodeID,dequeue_pri};
			tx_fifo_wren_0  <= 1'b1;
		end
		default:
		begin
			tx_fifo_wdata_7 <= 6'd0;
			tx_fifo_wren_7  <= 1'b0;
			tx_fifo_wdata_6 <= 6'd0;
			tx_fifo_wren_6  <= 1'b0;
			tx_fifo_wdata_5 <= 6'd0;
			tx_fifo_wren_5  <= 1'b0;
			tx_fifo_wdata_4 <= 6'd0;
			tx_fifo_wren_4  <= 1'b0;
			tx_fifo_wdata_3 <= 6'd0;
			tx_fifo_wren_3  <= 1'b0;
			tx_fifo_wdata_2 <= 6'd0;
			tx_fifo_wren_2  <= 1'b0;
			tx_fifo_wdata_1 <= 6'd0;
			tx_fifo_wren_1  <= 1'b0;
			tx_fifo_wdata_0 <= 6'd0;
			tx_fifo_wren_0  <= 1'b0;
		end
	endcase
	end
	else begin
		tx_fifo_wdata_7 <= 6'd0;
		tx_fifo_wren_7  <= 1'b0;
		tx_fifo_wdata_6 <= 6'd0;
		tx_fifo_wren_6  <= 1'b0;
		tx_fifo_wdata_5 <= 6'd0;
		tx_fifo_wren_5  <= 1'b0;
		tx_fifo_wdata_4 <= 6'd0;
		tx_fifo_wren_4  <= 1'b0;
		tx_fifo_wdata_3 <= 6'd0;
		tx_fifo_wren_3  <= 1'b0;
		tx_fifo_wdata_2 <= 6'd0;
		tx_fifo_wren_2  <= 1'b0;
		tx_fifo_wdata_1 <= 6'd0;
		tx_fifo_wren_1  <= 1'b0;
		tx_fifo_wdata_0 <= 6'd0;
		tx_fifo_wren_0  <= 1'b0;
	end
end

// assign dequeue_indicate_length_wr_en = (n_state == UPDATE);

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		dequeue_indicate_length_wr_data 		<= 64'b0;
		dequeue_indicate_length_wr_en 			<=  1'b0;
		dequeue_indicate_length_wr_addr 		<=  3'b0;
	end
	else if (((c_state == WR_UNI_TXFIFO) && (uni_match_en == 1'b1) && (tx_fifo_full_uni[dequeue_pri] == 1'b0)) || ((c_state == WR_MUL_TXFIFO) && (mul_match_en == 1'b1) && (tx_fifo_full_mul == 1'b0))) begin
		dequeue_indicate_length_wr_en 	<= 1'b1;
		//原来：dequeue_indicate_length_wr_data <= dequeue_NodeID;
		//修改：dequeue_indicate_length_wr_addr <= dequeue_NodeID;
		dequeue_indicate_length_wr_addr <= dequeue_NodeID;
		if ((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == dequeue_NodeID)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
            3'b000: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: dequeue_indicate_length_wr_data <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:dequeue_indicate_length_wr_data <= indicate_length_data_node0;
		endcase
		end
		else begin
		case(dequeue_pri)
            3'b000: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63: 8],dequeue_indicate_length_rd_data[ 7: 0]-8'd1};
            3'b001: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:16],dequeue_indicate_length_rd_data[15: 8]-8'd1,dequeue_indicate_length_rd_data[7:0]};
            3'b010: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:24],dequeue_indicate_length_rd_data[23:16]-8'd1,dequeue_indicate_length_rd_data[15:0]};
            3'b011: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:32],dequeue_indicate_length_rd_data[31:24]-8'd1,dequeue_indicate_length_rd_data[23:0]};
            3'b100: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:40],dequeue_indicate_length_rd_data[39:32]-8'd1,dequeue_indicate_length_rd_data[31:0]};
            3'b101: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:48],dequeue_indicate_length_rd_data[47:40]-8'd1,dequeue_indicate_length_rd_data[39:0]};
            3'b110: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:56],dequeue_indicate_length_rd_data[55:48]-8'd1,dequeue_indicate_length_rd_data[47:0]};
            3'b111: dequeue_indicate_length_wr_data <= {dequeue_indicate_length_rd_data[63:56]-8'd1,dequeue_indicate_length_rd_data[55:0]};
            default:dequeue_indicate_length_wr_data <= dequeue_indicate_length_rd_data;
        endcase
		end
	end
	else begin
		dequeue_indicate_length_wr_data <= dequeue_indicate_length_wr_data;
		dequeue_indicate_length_wr_en 	<= 1'b0;
		dequeue_indicate_length_wr_addr <= dequeue_indicate_length_wr_addr;
	end
end



//根据出队端口号查询物理队长
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_data_node0 		<= 64'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'b0) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'b0)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
            3'b000: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: indicate_length_data_node0 <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:indicate_length_data_node0 <= indicate_length_data_node0;
		endcase
		end
		else if(dequeue_NodeID == 3'b0) begin
			indicate_length_data_node0 <= dequeue_indicate_length_wr_data;
		end
		else begin
			indicate_length_data_node0 <= indicate_length_data_node0;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'b0)) begin
		indicate_length_data_node0 <= enqueue_indicate_length_wr_data;
	end
	else begin
		indicate_length_data_node0 <= indicate_length_data_node0;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_sum0 		<= 11'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd0) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd0)) begin // 入队和出队同时更新同一结点
			indicate_length_sum0 <= indicate_length_sum0;
		end
		else if(dequeue_NodeID == 3'd0) begin
            indicate_length_sum0 <= indicate_length_sum0 - 11'b1;
		end
		else begin
			indicate_length_sum0 <= indicate_length_sum0;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd0)) begin
		indicate_length_sum0 <= indicate_length_sum0 + 11'b1;
	end
	else begin
		indicate_length_sum0 <= indicate_length_sum0;
	end
end



always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_data_node1 		<= 64'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'b1) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'b1)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
            3'b000: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: indicate_length_data_node1 <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:indicate_length_data_node1 <= indicate_length_data_node1;
		endcase
		end
		else if(dequeue_NodeID == 3'b1) begin
			indicate_length_data_node1 <= dequeue_indicate_length_wr_data;
		end
		else begin
			indicate_length_data_node1 <= indicate_length_data_node1;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'b1)) begin
		indicate_length_data_node1 <= enqueue_indicate_length_wr_data;
	end
	else begin
		indicate_length_data_node1 <= indicate_length_data_node1;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_sum1 		<= 11'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd1) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd1)) begin // 入队和出队同时更新同一结点
			indicate_length_sum1 <= indicate_length_sum1;
		end
		else if(dequeue_NodeID == 3'd1) begin
            indicate_length_sum1 <= indicate_length_sum1 - 11'b1;
		end
		else begin
			indicate_length_sum1 <= indicate_length_sum1;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd1)) begin
		indicate_length_sum1 <= indicate_length_sum1 + 11'b1;
	end
	else begin
		indicate_length_sum1 <= indicate_length_sum1;
	end
end


always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_data_node2 		<= 64'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd2) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd2)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
			3'b000: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: indicate_length_data_node2 <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:indicate_length_data_node2 <= indicate_length_data_node2;
		endcase
		end
		else if(dequeue_NodeID == 3'd2) begin
			indicate_length_data_node2 <= dequeue_indicate_length_wr_data;
		end
		else begin
			indicate_length_data_node2 <= indicate_length_data_node2;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd2)) begin
		indicate_length_data_node2 <= enqueue_indicate_length_wr_data;
	end
	else begin
		indicate_length_data_node2 <= indicate_length_data_node2;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_sum2 		<= 11'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd2) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd2)) begin // 入队和出队同时更新同一结点
			indicate_length_sum2 <= indicate_length_sum2;
		end
		else if(dequeue_NodeID == 3'd2) begin
            indicate_length_sum2 <= indicate_length_sum2 - 11'b1;
		end
		else begin
			indicate_length_sum2 <= indicate_length_sum2;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd2)) begin
		indicate_length_sum2 <= indicate_length_sum2 + 11'b1;
	end
	else begin
		indicate_length_sum2 <= indicate_length_sum2;
	end
end


always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_data_node3 		<= 64'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd3) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd3)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
            3'b000: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: indicate_length_data_node3 <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:indicate_length_data_node3 <= indicate_length_data_node3;
		endcase
		end
		else if(dequeue_NodeID == 3'd3) begin
			indicate_length_data_node3 <= dequeue_indicate_length_wr_data;
		end
		else begin
			indicate_length_data_node3 <= indicate_length_data_node3;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd3)) begin
		indicate_length_data_node3 <= enqueue_indicate_length_wr_data;
	end
	else begin
		indicate_length_data_node3 <= indicate_length_data_node3;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_sum3 		<= 11'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd3) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd3)) begin // 入队和出队同时更新同一结点
			indicate_length_sum3 <= indicate_length_sum3;
		end
		else if(dequeue_NodeID == 3'd3) begin
            indicate_length_sum3 <= indicate_length_sum3 - 11'b1;
		end
		else begin
			indicate_length_sum3 <= indicate_length_sum3;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd3)) begin
		indicate_length_sum3 <= indicate_length_sum3 + 11'b1;
	end
	else begin
		indicate_length_sum3 <= indicate_length_sum3;
	end
end


always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_data_mul <= 64'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd4) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd4)) begin // 入队和出队同时更新同一结点
		case(dequeue_pri)
            3'b000: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63: 8],enqueue_indicate_length_wr_data[ 7: 0]-8'd1};
            3'b001: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:16],enqueue_indicate_length_wr_data[15: 8]-8'd1,enqueue_indicate_length_wr_data[7:0]};
            3'b010: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:24],enqueue_indicate_length_wr_data[23:16]-8'd1,enqueue_indicate_length_wr_data[15:0]};
            3'b011: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:32],enqueue_indicate_length_wr_data[31:24]-8'd1,enqueue_indicate_length_wr_data[23:0]};
            3'b100: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:40],enqueue_indicate_length_wr_data[39:32]-8'd1,enqueue_indicate_length_wr_data[31:0]};
            3'b101: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:48],enqueue_indicate_length_wr_data[47:40]-8'd1,enqueue_indicate_length_wr_data[39:0]};
            3'b110: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:56],enqueue_indicate_length_wr_data[55:48]-8'd1,enqueue_indicate_length_wr_data[47:0]};
            3'b111: indicate_length_data_mul <= {enqueue_indicate_length_wr_data[63:56]-8'd1,enqueue_indicate_length_wr_data[55:0]};
            default:indicate_length_data_mul <= indicate_length_data_mul;
		endcase
		end
		else if(dequeue_NodeID == 3'd4) begin
			//indicate_length_data_mul <= dequeue_indicate_length_wr_addr;
			indicate_length_data_mul <= dequeue_indicate_length_wr_data;
		end
		else begin
			indicate_length_data_mul <= indicate_length_data_mul;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd4)) begin
		indicate_length_data_mul <= enqueue_indicate_length_wr_data;
	end
	else begin
		indicate_length_data_mul <= indicate_length_data_mul;
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		indicate_length_sum4 		<= 11'b0;
	end
	else if (c_state == UPDATE) begin
		if ((dequeue_NodeID == 3'd4) && (enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd4)) begin // 入队和出队同时更新同一结点
			indicate_length_sum4 <= indicate_length_sum4;
		end
		else if(dequeue_NodeID == 3'd4) begin
            indicate_length_sum4 <= indicate_length_sum4 - 11'b1;
		end
		else begin
			indicate_length_sum4 <= indicate_length_sum4;
		end
	end
	else if((enqueue_indicate_length_wr_en) && (enqueue_indicate_length_wr_addr == 3'd4)) begin
		indicate_length_sum4 <= indicate_length_sum4 + 11'b1;
	end
	else begin
		indicate_length_sum4 <= indicate_length_sum4;
	end
end

//更新bit掩码表--
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		port_state_bit[0] <= 1'd0;
	end
	else if((c_state == UPDATE) && (dequeue_NodeID == 3'd0)) begin // 出队更新端口列表
		if(port_state_bit_val && (port_state_bit_set == 3'd0)) begin
			port_state_bit[0] <= port_state_bit[0];
		end
		else if(indicate_length_sum0 == 11'b1) begin
			port_state_bit[0] <= 1'b0;
		end
		else begin
			port_state_bit[0] <= port_state_bit[0];
		end
	end
	else if(port_state_bit_val && (port_state_bit_set == 3'd0)) begin
		port_state_bit[0] <= 1'b1;
	end
	else begin
		port_state_bit[0] <= port_state_bit[0];
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		port_state_bit[1] <= 1'd0;
	end
	else if((c_state == UPDATE) && (dequeue_NodeID == 3'd1)) begin // 出队更新端口列表
		if(port_state_bit_val && (port_state_bit_set == 3'd1)) begin
			port_state_bit[1] <= port_state_bit[1];
		end
		else if(indicate_length_sum1 == 11'b1) begin
			port_state_bit[1] <= 1'b0;
		end
		else begin
			port_state_bit[1] <= port_state_bit[1];
		end
	end
	else if(port_state_bit_val && (port_state_bit_set == 3'd1)) begin
		port_state_bit[1] <= 1'b1;
	end
	else begin
		port_state_bit[1] <= port_state_bit[1];
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		port_state_bit[2] <= 1'd0;
	end
	else if((c_state == UPDATE) && (dequeue_NodeID == 3'd2)) begin // 出队更新端口列表
		if(port_state_bit_val && (port_state_bit_set == 3'd2)) begin
			port_state_bit[2] <= port_state_bit[2];
		end
		else if(indicate_length_sum2 == 11'b1) begin
			port_state_bit[2] <= 1'b0;
		end
		else begin
			port_state_bit[2] <= port_state_bit[2];
		end
	end
	else if(port_state_bit_val && (port_state_bit_set == 3'd2)) begin
		port_state_bit[2] <= 1'b1;
	end
	else begin
		port_state_bit[2] <= port_state_bit[2];
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		port_state_bit[3] <= 1'd0;
	end
	else if((c_state == UPDATE) && (dequeue_NodeID == 3'd3)) begin // 出队更新端口列表
		if(port_state_bit_val && (port_state_bit_set == 3'd3)) begin
			port_state_bit[3] <= port_state_bit[0];
		end
		else if(indicate_length_sum3 == 11'b1) begin
			port_state_bit[3] <= 1'b0;
		end
		else begin
			port_state_bit[3] <= port_state_bit[3];
		end
	end
	else if(port_state_bit_val && (port_state_bit_set == 3'd3)) begin
		port_state_bit[3] <= 1'b1;
	end
	else begin
		port_state_bit[3] <= port_state_bit[3];
	end
end

always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		port_state_bit[4] <= 1'd0;
	end
	else if((c_state == UPDATE) && (dequeue_NodeID == 3'd4)) begin // 出队更新端口列表
		if(port_state_bit_val && (port_state_bit_set == 3'd4)) begin
			port_state_bit[4] <= port_state_bit[4];
		end
		else if(indicate_length_sum4 == 11'b1) begin
			port_state_bit[4] <= 1'b0;
		end
		else begin
			port_state_bit[4] <= port_state_bit[4];
		end
	end
	else if(port_state_bit_val && (port_state_bit_set == 3'd4)) begin
		port_state_bit[4] <= 1'b1;
	end
	else begin
		port_state_bit[4] <= port_state_bit[4];
	end
end


//mark debug
(*mark_debug = "true"*) reg [31:0] tx_gen_cnt;
always @(posedge clk or negedge rst_n) begin
	if (~rst_n) begin
		tx_gen_cnt <= 32'd0;
	end
	else if (c_state == UPDATE) begin
		tx_gen_cnt <= tx_gen_cnt + 1'b1;
	end
	else begin
		tx_gen_cnt <= tx_gen_cnt;
	end
end

endmodule
